# Required Packages
import pandas as pd
import numpy as np
import pandas_datareader.data as pdr
from datetime import datetime, timedelta
import requests
# Visualisation libraries
## Text
from colorama import Fore, Back, Style
from IPython.display import Image, display, Markdown, Latex, clear_output
## progressbar
import progressbar
## plotly
from plotly.offline import init_notebook_mode, iplot
import plotly.graph_objs as go
import plotly.offline as py
from plotly.subplots import make_subplots
import plotly.express as px
## seaborn
import seaborn as sns
## matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Polygon
from matplotlib.font_manager import FontProperties
import matplotlib.dates as mdates
plt.style.use('seaborn-whitegrid')
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
plt.rcParams['text.color'] = 'k'
%matplotlib inline
## WordCloud
from wordcloud import WordCloud
import warnings
warnings.filterwarnings("ignore")
In this article, the Technology Services from Yahoo! Finance is used, and we analyze the current top tech companies' stock prices.
N = 30
Link = 'https://finance.yahoo.com/screener/predefined/ms_technology?offset=0&count=100'
# df = pd.read_html(Link)
# df = pd.concat(df)
r = requests.get(Link,headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'})
df = pd.read_html(r.text)[0]
del Link, r
df['Market Cap Numeric'] = df['Market Cap'].replace(regex=['T'], value='e12').replace(regex=['B'], value='e9')\
.replace(regex=['M'], value='e6').astype(float)
df = df.sort_values(by = ['Market Cap Numeric'], ascending = False)
# df = df..drop_duplicates(subset=['Name'])
df = df[:N]
Symbols_list = df['Symbol'].tolist()
Symbols_Dic = dict(zip(df['Symbol'].tolist(), df['Name'].tolist()))
display(df.style.hide_index().set_precision(2).format({'Market Cap Numeric': "{:.4e}"})\
.bar(subset=['Market Cap Numeric'], align='mid', color=['Lime'])\
.set_properties(subset=['Symbol'], **{'background-color': 'Indigo', 'color': 'White'}))
| Symbol | Name | Price (Intraday) | Change | % Change | Volume | Avg Vol (3 month) | Market Cap | PE Ratio (TTM) | 52 Week Range | Market Cap Numeric |
|---|---|---|---|---|---|---|---|---|---|---|
| AAPL | Apple Inc. | 147.540000 | 0.590000 | +0.40% | 21.369M | 81.387M | 2.439T | 28.880000 | nan | 2.4390e+12 |
| MSFT | Microsoft Corporation | 288.280000 | 1.770000 | +0.62% | 5.194M | 23.817M | 2.166T | 35.810000 | nan | 2.1660e+12 |
| TSM | Taiwan Semiconductor Manufacturing Company Limited | 119.000000 | 0.260000 | +0.22% | 1.433M | 8.285M | 617.134B | 31.070000 | nan | 6.1713e+11 |
| NVDA | NVIDIA Corporation | 205.410000 | 2.670000 | +1.32% | 10.297M | 39.518M | 511.882B | 97.120000 | nan | 5.1188e+11 |
| ASML | ASML Holding N.V. | 796.210000 | 0.730000 | +0.09% | 368696 | 749825 | 326.269B | 58.430000 | nan | 3.2627e+11 |
| ADBE | Adobe Inc. | 629.020000 | 3.340000 | +0.53% | 363583 | 1.974M | 299.663B | 54.510000 | nan | 2.9966e+11 |
| ORCL | Oracle Corporation | 88.830000 | -1.220000 | -1.35% | 3.212M | 11.985M | 248.027B | 19.520000 | nan | 2.4803e+11 |
| CRM | salesforce.com, inc. | 249.360000 | 5.190000 | +2.13% | 1.553M | 6.004M | 242.26B | 52.570000 | nan | 2.4226e+11 |
| CSCO | Cisco Systems, Inc. | 55.830000 | 0.150000 | +0.26% | 3.211M | 17.96M | 235.3B | 23.080000 | nan | 2.3530e+11 |
| INTC | Intel Corporation | 53.930000 | 0.380000 | +0.70% | 6.015M | 23.729M | 218.794B | 11.980000 | nan | 2.1879e+11 |
| ACN | Accenture plc | 318.450000 | 1.680000 | +0.53% | 427108 | 1.913M | 201.941B | 35.580000 | nan | 2.0194e+11 |
| AVGO | Broadcom Inc. | 488.550000 | 0.750000 | +0.15% | 307710 | 1.65M | 200.433B | 45.410000 | nan | 2.0043e+11 |
| SHOP | Shopify Inc. | 1572.040000 | 16.520000 | +1.06% | 441106 | 1.435M | 196.414B | 80.750000 | nan | 1.9641e+11 |
| TXN | Texas Instruments Incorporated | 193.040000 | 0.660000 | +0.34% | 947143 | 4.035M | 178.216B | 26.920000 | nan | 1.7822e+11 |
| SAP | SAP SE | 148.970000 | 2.580000 | +1.76% | 261292 | 625440 | 175.783B | 25.290000 | nan | 1.7578e+11 |
| QCOM | QUALCOMM Incorporated | 146.140000 | -2.080000 | -1.40% | 3.598M | 7.816M | 164.846B | 18.260000 | nan | 1.6485e+11 |
| INTU | Intuit Inc. | 538.270000 | 2.210000 | +0.41% | 239050 | 1.173M | 147.087B | 68.240000 | nan | 1.4709e+11 |
| AMD | Advanced Micro Devices, Inc. | 112.510000 | -6.260000 | -5.27% | 66.99M | 50.246M | 136.467B | 39.660000 | nan | 1.3647e+11 |
| SQ | Square, Inc. | 287.700000 | 21.280000 | +7.99% | 10.942M | 9.479M | 132.255B | 259.660000 | nan | 1.3226e+11 |
| AMAT | Applied Materials, Inc. | 143.620000 | 0.860000 | +0.60% | 1.461M | 8.051M | 131.266B | 29.910000 | nan | 1.3127e+11 |
| IBM | International Business Machines Corporation | 142.430000 | -0.330000 | -0.23% | 1.014M | 4.545M | 127.658B | 24.070000 | nan | 1.2766e+11 |
| SONY | Sony Group Corporation | 102.860000 | 0.600000 | +0.59% | 149114 | 685382 | 127.464B | 11.970000 | nan | 1.2746e+11 |
| ZM | Zoom Video Communications, Inc. | 397.650000 | -2.930000 | -0.73% | 1.656M | 3.218M | 118.088B | 137.120000 | nan | 1.1809e+11 |
| NOW | ServiceNow, Inc. | 594.460000 | 0.990000 | +0.17% | 157408 | 1.367M | 117.762B | 699.360000 | nan | 1.1776e+11 |
| INFY | Infosys Limited | 22.580000 | -0.060000 | -0.24% | 1.568M | 6.049M | 95.8B | 34.750000 | nan | 9.5800e+10 |
| LRCX | Lam Research Corporation | 651.210000 | 1.430000 | +0.22% | 193060 | 1.262M | 92.798B | 24.210000 | nan | 9.2798e+10 |
| MU | Micron Technology, Inc. | 81.710000 | -0.270000 | -0.32% | 7.27M | 19.099M | 91.991B | 22.550000 | nan | 9.1991e+10 |
| TEAM | Atlassian Corporation Plc | 339.030000 | -1.410000 | -0.41% | 273674 | 1.325M | 84.779B | nan | nan | 8.4779e+10 |
| UBER | Uber Technologies, Inc. | 44.510000 | 2.700000 | +6.47% | 34.838M | 21.893M | 83.598B | nan | nan | 8.3598e+10 |
| SNOW | Snowflake Inc. | 277.090000 | 3.720000 | +1.36% | 1.357M | 4.432M | 82.046B | nan | nan | 8.2046e+10 |
start, end = [datetime(datetime.today().year-5, 1, 1), datetime.today()]
def Timeline_plot(start, end, width = 16):
fig, ax = plt.subplots(figsize=(width, 1))
Temp = pd.date_range(start, datetime(end.year, end.month, 1), freq='MS')
ax.plot((start, end), (0, 0), 'k', alpha=.5)
ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=2))
ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y"))
#fig.autofmt_xdate()
_ = plt.setp((ax.get_yticklabels() + ax.get_yticklines() + list(ax.spines.values())), visible=False)
for i in Temp:
ax.scatter(i, 0, s=30, facecolor='#e74c3c', edgecolor='k')
ax.grid(False)
_ = plt.xticks(rotation=90)
Temp1 = Temp.min().replace(day=1) - timedelta(days=1)
Temp2 = Temp.max().replace(day=1) + timedelta(days=31)
_ = ax.set_xlim ([datetime(Temp1.year,Temp1.month, 1), datetime(Temp2.year,Temp2.month, 1)])
Timeline_plot(start, end)
Collecting data from Yahoo Finance!, and creating moving Averages for 10, 20 and 60 day periods of time.
def Get_Data(Inp):
Days = [10, 20, 60]
Out = pdr.DataReader(Inp, 'yahoo', start, end)
Out.insert(0, 'Symbol', Inp)
for j in Days:
column_name = "Moving Ave. %s days" % (str(j))
Out[column_name] = Out['Adj Close'].rolling(window=j, center=False).mean()
return Out
Data = Get_Data(Symbols_list[0])
Counter = 0
Progress_Bar = progressbar.ProgressBar(maxval=len(Symbols_list),
widgets=[progressbar.Bar('#', '|', '|'), progressbar.Percentage()])
Progress_Bar.start()
for i in Symbols_list[1:]:
Counter+=1
Progress_Bar.update(Counter)
Temp = Get_Data(i)
Data = pd.concat([Data, Temp])
del Temp
Progress_Bar.finish()
Data [list(set(Data.columns)-{'Symbol'})] = Data[list(set(Data.columns)-{'Symbol'})].astype(float)
|#########################################################################|100%
Displaying today's data only:
Today = Data[Data.index == Data.index[-1]].reset_index(drop = True)
Today[list(set(Today.columns)-{'Symbol'})] = Today[list(set(Today.columns)-{'Symbol'})].astype(float)
display(Today.style.hide_index().set_precision(2).bar(subset=['Volume'], align='mid', color=['Lime'])\
.bar(subset=['Adj Close'], align='mid', color=['Salmon'])\
.set_properties(subset=['Symbol'], **{'background-color': 'Indigo', 'color': 'White'}))
print('Currently, the stock with the highest volume is %s' %
Symbols_Dic[Today[Today.Volume == Today.Volume.max()].Symbol.values[0]])
| Symbol | High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days |
|---|---|---|---|---|---|---|---|---|---|
| AAPL | 147.84 | 146.17 | 146.98 | 147.55 | 21373123.00 | 147.55 | 146.82 | 146.41 | 135.48 |
| MSFT | 288.82 | 286.10 | 286.88 | 288.27 | 5198634.00 | 288.27 | 286.96 | 283.70 | 266.00 |
| TSM | 119.20 | 118.24 | 119.07 | 119.02 | 1433279.00 | 119.02 | 116.69 | 117.89 | 116.64 |
| NVDA | 207.32 | 203.42 | 205.00 | 205.41 | 10299802.00 | 205.41 | 197.10 | 195.64 | 180.98 |
| ASML | 805.64 | 792.20 | 805.51 | 796.21 | 368696.00 | 796.21 | 768.10 | 735.67 | 694.53 |
| ADBE | 629.88 | 623.00 | 626.99 | 629.02 | 363583.00 | 629.02 | 622.39 | 615.07 | 561.04 |
| ORCL | 90.52 | 88.76 | 90.18 | 88.84 | 3213250.00 | 88.84 | 88.15 | 88.03 | 82.51 |
| CRM | 249.84 | 243.54 | 244.68 | 249.33 | 1554640.00 | 249.33 | 244.48 | 243.16 | 238.08 |
| CSCO | 55.94 | 55.50 | 55.52 | 55.83 | 3210733.00 | 55.83 | 55.44 | 54.56 | 53.43 |
| INTC | 54.02 | 53.58 | 53.99 | 53.92 | 6020858.00 | 53.92 | 53.65 | 54.78 | 55.86 |
| ACN | 318.90 | 317.04 | 317.91 | 318.45 | 427421.00 | 318.45 | 317.97 | 315.22 | 296.33 |
| AVGO | 490.43 | 485.38 | 490.43 | 488.51 | 308293.00 | 488.51 | 483.57 | 480.11 | 466.78 |
| SHOP | 1576.00 | 1533.85 | 1553.21 | 1572.04 | 441315.00 | 1572.04 | 1553.24 | 1527.30 | 1385.03 |
| TXN | 193.90 | 191.68 | 193.80 | 193.04 | 948066.00 | 193.04 | 189.30 | 188.69 | 187.07 |
| SAP | 149.12 | 148.45 | 148.53 | 148.97 | 261408.00 | 148.97 | 143.41 | 144.67 | 142.00 |
| QCOM | 147.46 | 144.57 | 147.24 | 146.16 | 3599483.00 | 146.16 | 146.37 | 143.83 | 137.64 |
| INTU | 539.55 | 534.76 | 536.74 | 538.27 | 239089.00 | 538.27 | 529.12 | 518.02 | 479.15 |
| AMD | 117.57 | 112.33 | 116.63 | 112.56 | 67159121.00 | 112.56 | 103.46 | 96.14 | 86.90 |
| SQ | 289.23 | 264.80 | 265.60 | 287.69 | 10953781.00 | 287.69 | 263.48 | 253.56 | 233.85 |
| AMAT | 143.69 | 141.16 | 143.43 | 143.68 | 1469961.00 | 143.68 | 139.71 | 136.89 | 135.19 |
| IBM | 143.41 | 142.22 | 143.03 | 142.46 | 1016010.00 | 142.46 | 142.22 | 141.20 | 143.94 |
| SONY | 103.99 | 102.11 | 103.97 | 102.86 | 149135.00 | 102.86 | 102.61 | 102.16 | 99.24 |
| ZM | 404.35 | 391.82 | 395.73 | 397.66 | 1660556.00 | 397.66 | 378.56 | 371.60 | 356.46 |
| NOW | 596.56 | 589.43 | 595.00 | 594.46 | 157419.00 | 594.46 | 586.76 | 574.85 | 526.12 |
| INFY | 22.79 | 22.58 | 22.74 | 22.58 | 1572828.00 | 22.58 | 22.14 | 21.62 | 20.39 |
| LRCX | 653.61 | 643.00 | 651.79 | 651.21 | 193153.00 | 651.21 | 638.36 | 626.77 | 627.40 |
| MU | 83.07 | 81.30 | 82.14 | 81.76 | 7280965.00 | 81.76 | 77.89 | 77.44 | 79.66 |
| TEAM | 342.85 | 335.38 | 340.21 | 339.03 | 273938.00 | 339.03 | 299.63 | 281.75 | 255.42 |
| UBER | 44.63 | 40.15 | 40.50 | 44.51 | 34889316.00 | 44.51 | 44.70 | 45.96 | 48.37 |
| SNOW | 277.93 | 268.41 | 270.65 | 277.10 | 1363081.00 | 277.10 | 270.31 | 264.69 | 246.81 |
Currently, the stock with the highest volume is Advanced Micro Devices, Inc.
Consider AAPL for example. We hAve,
def Header(Text, L = 100, C = 'Blue', T = 'White'):
BACK = {'Black': Back.BLACK, 'Red':Back.RED, 'Green':Back.GREEN, 'Yellow': Back.YELLOW, 'Blue': Back.BLUE,
'Magenta':Back.MAGENTA, 'Cyan': Back.CYAN}
FORE = {'Black': Fore.BLACK, 'Red':Fore.RED, 'Green':Fore.GREEN, 'Yellow':Fore.YELLOW, 'Blue':Fore.BLUE,
'Magenta':Fore.MAGENTA, 'Cyan':Fore.CYAN, 'White': Fore.WHITE}
print(BACK[C] + FORE[T] + Style.NORMAL + Text + Style.RESET_ALL + ' ' + FORE[C] +
Style.NORMAL + (L- len(Text) - 1)*'=' + Style.RESET_ALL)
def Line(L=100, C = 'Blue'):
FORE = {'Black': Fore.BLACK, 'Red':Fore.RED, 'Green':Fore.GREEN, 'Yellow':Fore.YELLOW, 'Blue':Fore.BLUE,
'Magenta':Fore.MAGENTA, 'Cyan':Fore.CYAN, 'White': Fore.WHITE}
print(FORE[C] + Style.NORMAL + L*'=' + Style.RESET_ALL)
def Disp_Data(Inp, df = Data):
Out = df[df.Symbol == Inp].drop(columns=['Symbol'])
return Out
Temp = Disp_Data('AAPL')
display(Temp.describe().round(2))
Tag = Temp.head(7).index[[0,-1]].astype(str).tolist()
Header('From %s To %s' % (Tag[0],Tag[1]))
display(Temp.head(7).dropna(axis = 1).round(2))
Tag = Temp.tail(7).index[[0,-1]].astype(str).tolist()
Header('From %s To %s' % (Tag[0],Tag[1]))
display(Temp.tail(7).round(2))
del Temp, Tag
Line()
| High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days | |
|---|---|---|---|---|---|---|---|---|---|
| count | 1408.00 | 1408.00 | 1408.00 | 1408.00 | 1.408000e+03 | 1408.00 | 1399.00 | 1389.00 | 1349.00 |
| mean | 60.81 | 59.54 | 60.16 | 60.21 | 1.294779e+08 | 59.02 | 58.85 | 58.67 | 58.03 |
| std | 35.33 | 34.40 | 34.89 | 34.89 | 6.010780e+07 | 35.40 | 35.06 | 34.68 | 33.35 |
| min | 22.92 | 22.37 | 22.50 | 22.58 | 2.137312e+07 | 21.10 | 21.64 | 21.92 | 22.46 |
| 25% | 36.77 | 36.19 | 36.39 | 36.46 | 8.930602e+07 | 34.72 | 34.98 | 35.27 | 35.61 |
| 50% | 47.20 | 46.44 | 46.80 | 46.82 | 1.127104e+08 | 45.46 | 45.35 | 45.50 | 45.89 |
| 75% | 75.28 | 73.21 | 74.15 | 74.56 | 1.505374e+08 | 73.75 | 73.26 | 73.04 | 71.11 |
| max | 150.00 | 147.70 | 149.24 | 149.15 | 5.334788e+08 | 149.15 | 146.91 | 146.41 | 135.48 |
From 2016-01-04 To 2016-01-12 ======================================================================
| High | Low | Open | Close | Volume | Adj Close | |
|---|---|---|---|---|---|---|
| Date | ||||||
| 2016-01-04 | 26.34 | 25.50 | 25.65 | 26.34 | 270597600.0 | 24.32 |
| 2016-01-05 | 26.46 | 25.60 | 26.44 | 25.68 | 223164000.0 | 23.71 |
| 2016-01-06 | 25.59 | 24.97 | 25.14 | 25.17 | 273829600.0 | 23.25 |
| 2016-01-07 | 25.03 | 24.11 | 24.67 | 24.11 | 324377600.0 | 22.27 |
| 2016-01-08 | 24.78 | 24.19 | 24.64 | 24.24 | 283192000.0 | 22.39 |
| 2016-01-11 | 24.76 | 24.33 | 24.74 | 24.63 | 198957600.0 | 22.75 |
| 2016-01-12 | 25.17 | 24.71 | 25.14 | 24.99 | 196616800.0 | 23.08 |
From 2021-07-28 To 2021-08-05 ======================================================================
| High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days | |
|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||
| 2021-07-28 | 146.97 | 142.54 | 144.81 | 144.98 | 118931200.0 | 144.98 | 146.50 | 144.67 | 133.63 |
| 2021-07-29 | 146.55 | 144.58 | 144.69 | 145.64 | 56699500.0 | 145.64 | 146.21 | 145.10 | 133.93 |
| 2021-07-30 | 146.33 | 144.11 | 144.38 | 145.86 | 70382000.0 | 145.86 | 146.16 | 145.53 | 134.23 |
| 2021-08-02 | 146.95 | 145.25 | 146.36 | 145.52 | 62880000.0 | 145.52 | 146.47 | 145.81 | 134.50 |
| 2021-08-03 | 148.04 | 145.18 | 145.81 | 147.36 | 64660800.0 | 147.36 | 146.59 | 146.08 | 134.79 |
| 2021-08-04 | 147.79 | 146.28 | 147.27 | 146.95 | 56319800.0 | 146.95 | 146.74 | 146.20 | 135.12 |
| 2021-08-05 | 147.84 | 146.17 | 146.98 | 147.55 | 21373123.0 | 147.55 | 146.82 | 146.41 | 135.48 |
====================================================================================================
Temp = Data[['Symbol','Adj Close']].reset_index(drop = False)
Temp['Symbol'] = Temp['Symbol'].replace(Symbols_Dic)
fig = px.line(Data.reset_index(drop = False), x='Date', y='Adj Close', color= 'Symbol')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Day', step='day', stepmode='todate'),
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='This Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + 'Stock Prices Fluctuations' + '<b>',
'x':.5, 'y': .98, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
del Temp
The following table shows the Average values for all columns of the Data.
def List_Search(List, Key): return [s for s in List if Key in s]
def List_Diff(Inp_A, Inp_B):
# Inp_A: A list
# Inp_B: A list
Out=list(set(Inp_A)-set(Inp_B))
return Out
# Creating a new list of Columns
Columns = List_Diff(Data.columns.tolist(), List_Search(Data.columns.tolist(), 'Moving Ave'))
Columns = List_Diff(Columns, ['Symbol'])
Temp = ['Ave. ' + i for i in Columns]
# A new DataFrame
Ave_df = pd.DataFrame({'Symbol':Symbols_list})
for i in Temp:
Ave_df[i]=''
del Temp
# Progress Bar
Counter = 0
Progress_Bar = progressbar.ProgressBar(maxval=len(Symbols_list),
widgets=[progressbar.Bar('#', '|', '|'), progressbar.Percentage()])
Progress_Bar.start()
for i in range(len(Symbols_list)):
Counter+=1
Progress_Bar.update(Counter)
Ave_df.iloc[i,1:] = Data[Data.Symbol == Symbols_list[i]][Columns].mean().values
Progress_Bar.finish()
display(Ave_df.style.hide_index().set_precision(2).bar(subset=['Ave. Volume'], align='mid', color=['Lime'])\
.bar(subset=['Ave. Adj Close'], align='mid', color=['Salmon'])\
.set_properties(subset=['Symbol'], **{'background-color': 'DimGray', 'color': 'White'}))
Temp = pd.melt(Ave_df, id_vars=['Symbol'], value_vars=list(set(Ave_df.columns)-{'Symbol'}),
var_name='Summary', value_name='Value')
fig = make_subplots(rows=2, cols=1, vertical_spacing = 0.1, shared_yaxes=True,
subplot_titles=('Ave. Volume', 'Summary'))
# Top
fig1 = px.bar(Ave_df.round(0), x= 'Symbol', y= 'Ave. Volume', orientation='v', text = 'Ave. Volume',
hover_data= Ave_df.columns)
for i in range(len(fig1['data'])):
fig.add_trace(fig1['data'][i], row=1, col=1)
fig.update_traces(marker_line_color= 'Black', marker_line_width=1, opacity=1, row=1, col=1)
# Bottom
fig2 = px.bar(Temp.loc[Temp.Summary != 'Ave. Volume'].round(0), x= 'Symbol', y = 'Value',
color = 'Summary', orientation='v', hover_data= Temp.columns)
for i in range(len(fig2['data'])):
fig.add_trace(fig2['data'][i], row=2, col=1)
fig.update_traces(marker_line_color= 'Black', marker_line_width=1, opacity=1, showlegend = True, row=2, col=1)
# Update
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
zeroline=False, zerolinewidth=1, zerolinecolor='Black',
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
zeroline=False, zerolinewidth=1, zerolinecolor='Black', title_text='Value',
showgrid=False, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(legend_orientation='v', plot_bgcolor= 'white', height= 800)
fig.update_layout(legend=dict(font=dict(color="Black"), bordercolor="Lightgray", borderwidth=1))
fig.update_layout(title={'text': '<b>' + 'Average Values' + '<b>', 'x':0.5, 'y': .95, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
|#########################################################################|100%
| Symbol | Ave. Close | Ave. High | Ave. Adj Close | Ave. Low | Ave. Open | Ave. Volume |
|---|---|---|---|---|---|---|
| AAPL | 60.21 | 60.81 | 59.02 | 59.54 | 60.16 | 129477866.00 |
| MSFT | 125.19 | 126.32 | 122.16 | 123.91 | 125.14 | 29202481.27 |
| TSM | 51.49 | 52.00 | 48.58 | 50.97 | 51.52 | 7926236.77 |
| NVDA | 61.52 | 62.47 | 61.27 | 60.45 | 61.50 | 50510999.43 |
| ASML | 246.33 | 248.58 | 242.16 | 243.72 | 246.17 | 837962.64 |
| ADBE | 263.90 | 266.73 | 263.90 | 260.56 | 263.82 | 2808699.99 |
| ORCL | 51.31 | 51.75 | 49.20 | 50.86 | 51.26 | 14142099.61 |
| CRM | 141.15 | 142.77 | 141.15 | 139.35 | 141.18 | 5899738.95 |
| CSCO | 41.09 | 41.45 | 38.01 | 40.71 | 41.08 | 22690096.54 |
| INTC | 46.69 | 47.20 | 44.03 | 46.17 | 46.67 | 26373744.08 |
| ACN | 172.02 | 173.35 | 165.90 | 170.54 | 171.91 | 2199161.80 |
| AVGO | 271.56 | 274.71 | 249.50 | 268.16 | 271.54 | 2923681.03 |
| SHOP | 375.10 | 382.91 | 375.10 | 365.99 | 374.73 | 1759822.81 |
| TXN | 108.97 | 110.04 | 102.39 | 107.80 | 108.92 | 5152775.62 |
| SAP | 113.31 | 114.00 | 108.71 | 112.53 | 113.27 | 867707.11 |
| QCOM | 77.43 | 78.37 | 72.57 | 76.49 | 77.44 | 11281422.64 |
| INTU | 223.41 | 225.65 | 219.93 | 220.75 | 223.26 | 1433710.50 |
| AMD | 32.41 | 33.04 | 32.41 | 31.74 | 32.40 | 60193716.07 |
| SQ | 76.51 | 78.14 | 76.51 | 74.74 | 76.49 | 9819281.02 |
| AMAT | 53.22 | 53.98 | 51.81 | 52.44 | 53.22 | 10556456.58 |
| IBM | 141.89 | 143.01 | 124.81 | 140.77 | 141.89 | 4720900.79 |
| SONY | 54.66 | 55.04 | 54.66 | 54.24 | 54.67 | 1131619.41 |
| ZM | 230.27 | 236.04 | 230.27 | 224.11 | 230.18 | 6266881.82 |
| NOW | 237.38 | 240.75 | 237.38 | 233.63 | 237.34 | 1845195.33 |
| INFY | 10.56 | 10.64 | 9.91 | 10.47 | 10.55 | 10735977.01 |
| LRCX | 234.62 | 238.10 | 227.79 | 230.95 | 234.54 | 2283200.11 |
| MU | 42.53 | 43.25 | 42.53 | 41.79 | 42.55 | 28932485.70 |
| TEAM | 101.68 | 103.44 | 101.68 | 99.63 | 101.51 | 1294396.97 |
| UBER | 40.07 | 40.90 | 40.07 | 39.22 | 40.12 | 23338468.52 |
| SNOW | 260.14 | 268.13 | 260.14 | 253.17 | 260.41 | 4292438.75 |
def TopN_volumes(N, df = Ave_df):
Out = df.sort_values(by='Ave. Volume', ascending=False).iloc[:N,0].tolist()
return Out
# Conisder the Moving Ave and Adj Close columns
Columns = List_Search(Data.columns.tolist(), 'Moving Ave.')
Columns.append("Adj Close")
Columns = list(np.sort(Columns))
# A list of top N = 4 companies with the hightest volume on Average.
N = 4
mylist = TopN_volumes(N)
# Conisder the Moving Ave and Adj Close columns
Columns = List_Search(Data.columns.tolist(), 'Moving Ave.')
Columns.append("Adj Close")
Columns = list(np.sort(Columns))
# A list of top N = 4 companies with the hightest volume on Average.
N = 4
mylist = Ave_df.sort_values(by='Ave. Volume', ascending=False).iloc[:N,0].tolist()
for symb in mylist:
Temp = Disp_Data(symb)[Columns].reset_index(drop = False)
Temp = pd.melt(Temp, id_vars=['Date'], value_vars= List_Diff(Temp.columns, ['Date']),
var_name='Variable', value_name='Value')
fig = px.line(Temp, x='Date', y='Value', color = 'Variable')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Day', step='day', stepmode='todate'),
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='This Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + Symbols_Dic[symb] + '<b>',
'x':.5, 'y': .97, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
del Temp
del symb
Daily return can be calculated using the percentage change of the adjusted closing price.
Daily_Return = Disp_Data(mylist[0])['Adj Close'].pct_change().to_frame('Daily Return').reset_index(drop = False)
Daily_Return['Symbols'] = mylist[0]
for stock in mylist[1:]:
Temp = Disp_Data(stock)['Adj Close'].pct_change().to_frame('Daily Return').reset_index(drop = False)
Temp['Symbols'] = stock
Daily_Return = pd.concat([Daily_Return, Temp])
del Temp, stock
Daily_Return = Daily_Return.sort_values('Date')
fig = px.line(Daily_Return, x='Date', y='Daily Return', color = 'Symbols')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Day', step='day', stepmode='todate'),
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='This Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + 'Daily Returns' + '<b>',
'x':.5, 'y': .95, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
del Daily_Return
First, we need to create a new data frame by reading the Adj Close column from all stock data under study. We hAve,
All_data = pdr.DataReader(Symbols_list, 'yahoo', start, end)['Adj Close']
All_returns = All_data.pct_change()
Tag = All_data.head(7).index[[0,-1]].astype(str).tolist()
Header('From %s To %s' % (Tag[0],Tag[1]), C = 'Black')
display(All_data.head(7).dropna(axis = 1).round(4))
Tag = All_data.tail(7).index[[0,-1]].astype(str).tolist()
Header('From %s To %s' % (Tag[0],Tag[1]), C = 'Black')
display(All_data.tail(7).dropna(axis = 1).round(4))
Line(C = 'Black')
From 2016-01-04 To 2016-01-12 ======================================================================
| Symbols | AAPL | MSFT | TSM | NVDA | ASML | ADBE | ORCL | CRM | CSCO | INTC | ... | AMD | SQ | AMAT | IBM | SONY | NOW | INFY | LRCX | MU | TEAM |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||||||||||||||
| 2016-01-04 | 24.3232 | 49.7769 | 18.3627 | 7.9135 | 82.3539 | 91.97 | 32.6963 | 76.71 | 22.1637 | 29.3546 | ... | 2.77 | 12.16 | 17.1064 | 106.7243 | 24.73 | 84.07 | 6.9735 | 70.9663 | 14.33 | 27.41 |
| 2016-01-05 | 23.7137 | 50.0040 | 18.2463 | 8.0407 | 81.5238 | 92.34 | 32.5957 | 77.05 | 22.0630 | 29.2164 | ... | 2.75 | 11.51 | 17.1249 | 106.6458 | 25.47 | 84.00 | 6.9563 | 71.3498 | 14.82 | 26.77 |
| 2016-01-06 | 23.2496 | 49.0956 | 17.7392 | 7.7082 | 79.8163 | 91.02 | 32.7603 | 76.29 | 21.8280 | 28.5687 | ... | 2.51 | 11.52 | 16.4210 | 106.1120 | 23.63 | 81.42 | 6.9005 | 67.1592 | 14.22 | 27.05 |
| 2016-01-07 | 22.2684 | 47.3880 | 17.5397 | 7.4026 | 77.8164 | 89.11 | 32.0470 | 74.30 | 21.3244 | 27.4978 | ... | 2.28 | 11.16 | 15.9394 | 104.2986 | 23.27 | 79.64 | 6.8962 | 65.4702 | 13.66 | 26.97 |
| 2016-01-08 | 22.3861 | 47.5333 | 17.2987 | 7.2437 | 75.7316 | 87.85 | 31.6903 | 73.23 | 20.7957 | 27.2128 | ... | 2.14 | 11.31 | 15.5504 | 103.3330 | 23.00 | 78.12 | 6.9434 | 64.3472 | 13.33 | 27.17 |
| 2016-01-11 | 22.7486 | 47.5061 | 17.3984 | 7.2559 | 77.6466 | 89.38 | 31.9555 | 73.18 | 21.2070 | 27.6878 | ... | 2.34 | 11.84 | 15.4485 | 104.5890 | 23.36 | 78.53 | 6.9778 | 64.7763 | 12.53 | 27.12 |
| 2016-01-12 | 23.0788 | 47.9421 | 17.2488 | 7.3781 | 77.9674 | 89.82 | 32.3488 | 74.46 | 21.2741 | 28.2232 | ... | 2.39 | 12.09 | 15.5134 | 104.3300 | 22.85 | 80.99 | 7.1152 | 65.2237 | 12.72 | 26.82 |
7 rows × 27 columns
From 2021-07-28 To 2021-08-05 ======================================================================
| Symbols | AAPL | MSFT | TSM | NVDA | ASML | ADBE | ORCL | CRM | CSCO | INTC | ... | IBM | SONY | ZM | NOW | INFY | LRCX | MU | TEAM | UBER | SNOW |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||||||||||||||
| 2021-07-28 | 144.98 | 286.22 | 115.07 | 195.0300 | 759.8600 | 620.920 | 87.18 | 243.96 | 54.770 | 53.07 | ... | 141.77 | 103.13 | 369.4900 | 583.35 | 21.850 | 635.00 | 75.55 | 269.08 | 46.1400 | 269.36 |
| 2021-07-29 | 145.64 | 286.50 | 116.15 | 196.6200 | 765.7100 | 621.700 | 87.63 | 244.04 | 55.070 | 53.70 | ... | 141.93 | 105.86 | 386.0200 | 586.43 | 21.920 | 619.63 | 77.08 | 266.79 | 44.6900 | 268.26 |
| 2021-07-30 | 145.86 | 284.91 | 116.64 | 194.9900 | 766.7400 | 621.630 | 87.14 | 241.93 | 55.370 | 53.72 | ... | 140.96 | 104.30 | 378.1000 | 587.89 | 22.120 | 637.41 | 77.58 | 325.12 | 43.4600 | 265.72 |
| 2021-08-02 | 145.52 | 284.82 | 116.86 | 197.5000 | 769.6500 | 618.750 | 87.60 | 240.86 | 55.450 | 53.68 | ... | 141.42 | 104.40 | 378.9600 | 584.67 | 22.270 | 641.80 | 77.64 | 322.58 | 43.4900 | 268.29 |
| 2021-08-03 | 147.36 | 287.12 | 118.41 | 198.1500 | 779.5300 | 621.280 | 89.74 | 241.13 | 56.250 | 54.06 | ... | 144.07 | 103.68 | 374.8800 | 584.66 | 22.880 | 645.52 | 80.86 | 329.42 | 42.7900 | 284.58 |
| 2021-08-04 | 146.95 | 286.51 | 118.74 | 202.7400 | 795.4800 | 625.680 | 90.05 | 244.17 | 55.690 | 53.90 | ... | 142.76 | 102.26 | 400.5800 | 593.47 | 22.640 | 649.78 | 81.98 | 340.44 | 41.8100 | 273.37 |
| 2021-08-05 | 147.53 | 288.24 | 119.05 | 205.4801 | 796.8173 | 629.255 | 88.81 | 249.36 | 55.835 | 53.94 | ... | 142.45 | 102.86 | 397.3606 | 594.63 | 22.585 | 651.66 | 81.77 | 339.03 | 44.5219 | 277.49 |
7 rows × 30 columns
====================================================================================================
The returns can be analyzed using the percentage change from the adj Close.
Tag = All_data.tail(7).index[[0,-1]].astype(str).tolist()
Header('Returns (From %s To %s)' % (Tag[0],Tag[1]), C = 'Cyan', T = 'Black')
display(All_returns.tail(7).round(4))
Temp = pd.melt(All_returns.reset_index(drop = False), id_vars=['Date'],
value_vars=list(set(All_returns.columns)-{'Date'}),
var_name='Symbols', value_name='Daily Return')
Temp['Symbols'] = Temp['Symbols'].replace(Symbols_Dic)
fig = px.line(Temp, x='Date', y='Daily Return', color = 'Symbols')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Day', step='day', stepmode='todate'),
dict(count=7, label='One Week', step='day', stepmode='todate'),
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='This Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + 'Daily Returns' + '<b>',
'x':.5, 'y': .98, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
Returns (From 2021-07-28 To 2021-08-05) ============================================================
| Symbols | AAPL | MSFT | TSM | NVDA | ASML | ADBE | ORCL | CRM | CSCO | INTC | ... | IBM | SONY | ZM | NOW | INFY | LRCX | MU | TEAM | UBER | SNOW |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||||||||||||||
| 2021-07-28 | -0.0122 | -0.0011 | 0.0135 | 0.0154 | 0.0191 | 0.0043 | -0.0071 | 0.0018 | -0.0092 | -0.0021 | ... | -0.0069 | 0.0351 | 0.0053 | 0.0018 | 0.0064 | 0.0199 | 0.0179 | 0.0155 | 0.0070 | 0.0254 |
| 2021-07-29 | 0.0046 | 0.0010 | 0.0094 | 0.0082 | 0.0077 | 0.0013 | 0.0052 | 0.0003 | 0.0055 | 0.0119 | ... | 0.0011 | 0.0265 | 0.0447 | 0.0053 | 0.0032 | -0.0242 | 0.0203 | -0.0085 | -0.0314 | -0.0041 |
| 2021-07-30 | 0.0015 | -0.0055 | 0.0042 | -0.0083 | 0.0013 | -0.0001 | -0.0056 | -0.0086 | 0.0054 | 0.0004 | ... | -0.0068 | -0.0147 | -0.0205 | 0.0025 | 0.0091 | 0.0287 | 0.0065 | 0.2186 | -0.0275 | -0.0095 |
| 2021-08-02 | -0.0023 | -0.0003 | 0.0019 | 0.0129 | 0.0038 | -0.0046 | 0.0053 | -0.0044 | 0.0014 | -0.0007 | ... | 0.0033 | 0.0010 | 0.0023 | -0.0055 | 0.0068 | 0.0069 | 0.0008 | -0.0078 | 0.0007 | 0.0097 |
| 2021-08-03 | 0.0126 | 0.0081 | 0.0133 | 0.0033 | 0.0128 | 0.0041 | 0.0244 | 0.0011 | 0.0144 | 0.0071 | ... | 0.0187 | -0.0069 | -0.0108 | -0.0000 | 0.0274 | 0.0058 | 0.0415 | 0.0212 | -0.0161 | 0.0607 |
| 2021-08-04 | -0.0028 | -0.0021 | 0.0028 | 0.0232 | 0.0205 | 0.0071 | 0.0035 | 0.0126 | -0.0100 | -0.0030 | ... | -0.0091 | -0.0137 | 0.0686 | 0.0151 | -0.0105 | 0.0066 | 0.0139 | 0.0335 | -0.0229 | -0.0394 |
| 2021-08-05 | 0.0039 | 0.0060 | 0.0026 | 0.0135 | 0.0017 | 0.0057 | -0.0138 | 0.0213 | 0.0026 | 0.0007 | ... | -0.0022 | 0.0059 | -0.0080 | 0.0020 | -0.0024 | 0.0029 | -0.0026 | -0.0041 | 0.0649 | 0.0151 |
7 rows × 30 columns
The following graphs show the correlation between different stocks.
_ = sns.jointplot(Symbols_list[0], Symbols_list[1], All_returns, kind='reg', space=0, size=6, ratio=4)
_ = sns.jointplot(Symbols_list[1], Symbols_list[2], All_returns, kind='reg', space=0, size=6, ratio=4)
Now, we can use the pairplot tool to visualize all.
# Remove missing values
Temp = TopN_volumes(8, df = Ave_df)
Temp = All_returns[Temp].dropna()
# plot
_ = sns.pairplot(Temp, diag_kind='kde')
Nonetheless, the correlation matrix and plot are always convenient to see numerical values for correlations.
# Correlation Matrix
Cor_matrix = Temp.corr()
display(Cor_matrix.style.set_caption('Correlation Matrix')\
.background_gradient(cmap=sns.diverging_palette(5, 250, as_cmap=True)))
def Correlation_Plot (Df,Fig_Size):
Correlation_Matrix = Df.corr()
mask = np.zeros_like(Correlation_Matrix)
mask[np.triu_indices_from(mask)] = True
for i in range(len(mask)):
mask[i,i]=0
Fig, ax = plt.subplots(figsize=(Fig_Size,Fig_Size))
sns.heatmap(Correlation_Matrix, ax=ax, mask=mask, annot=True, square=True,
cmap =sns.diverging_palette(5, 250, as_cmap=True), linewidths = 0.2, vmin=0, vmax=1, cbar_kws={"shrink": .5})
bottom, top = ax.get_ylim()
_ = ax.set_ylim(bottom + 0.5, top - 0.5)
Correlation_Plot (Temp, 10)
| Symbols | AAPL | AMD | NVDA | MSFT | MU | INTC | UBER | CSCO |
|---|---|---|---|---|---|---|---|---|
| Symbols | ||||||||
| AAPL | 1.000000 | 0.597042 | 0.714030 | 0.800231 | 0.540635 | 0.599078 | 0.334260 | 0.610872 |
| AMD | 0.597042 | 1.000000 | 0.718934 | 0.625224 | 0.542246 | 0.450520 | 0.369474 | 0.473224 |
| NVDA | 0.714030 | 0.718934 | 1.000000 | 0.766074 | 0.666178 | 0.619144 | 0.447154 | 0.554637 |
| MSFT | 0.800231 | 0.625224 | 0.766074 | 1.000000 | 0.602618 | 0.666380 | 0.393132 | 0.664182 |
| MU | 0.540635 | 0.542246 | 0.666178 | 0.602618 | 1.000000 | 0.686011 | 0.429522 | 0.562816 |
| INTC | 0.599078 | 0.450520 | 0.619144 | 0.666380 | 0.686011 | 1.000000 | 0.305410 | 0.598575 |
| UBER | 0.334260 | 0.369474 | 0.447154 | 0.393132 | 0.429522 | 0.305410 | 1.000000 | 0.344180 |
| CSCO | 0.610872 | 0.473224 | 0.554637 | 0.664182 | 0.562816 | 0.598575 | 0.344180 | 1.000000 |
Here, darker shades of blue represent a higher correlation.
Temp = All_returns.mean().to_frame('Expected Return').join(All_returns.std().to_frame('Risk')).reset_index(drop = False)
TOL = 1e-6
Temp['Expected Return'] = np.where(Temp['Expected Return'].values<TOL, 0, Temp['Expected Return'].values)
Temp['Symbols'] = Temp['Symbols'].replace(Symbols_Dic)
fig = px.scatter(Temp, x= 'Expected Return', y='Risk', color= 'Symbols',
size='Expected Return', hover_data=Temp.columns)
fig.update_traces(marker_line_color= 'Black', marker_line_width=1, opacity=.5, showlegend = True)
# Update
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
zeroline=False, zerolinewidth=1, zerolinecolor='Black', range= [0,0.004],
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True, range= [0,0.05],
zeroline=False, zerolinewidth=1, zerolinecolor='Black', title_text='Value',
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(legend_orientation='v', plot_bgcolor= 'white', height= 500)
fig.show()
print("""The current trend seems to output a value between %.2e and %.2e.
We would like to identify a stock with high return and low risk!
""" % (Temp['Expected Return'].min(),Temp['Expected Return'].max()))
The current trend seems to output a value between 3.36e-04 and 4.17e-03. We would like to identify a stock with high return and low risk!
We can find the quantile as well.
print('quantile for %s' % Symbols_list[0])
qt = All_returns[Symbols_list[0]].quantile(0.05)
qt_pct = abs(All_returns[Symbols_list[0]].quantile(0.05))*100
print('Quantile Percentage: %0.4f' % qt_pct)
print("""The 0.05 empirical quantile of daily returns is at {0:.2f}%.
This means that with 95% confidence, the worst daily loss will not exceed {0:.2f}% (of the investment)."""
.format(qt,qt_pct))
quantile for AAPL
Quantile Percentage: 2.6944
The 0.05 empirical quantile of daily returns is at -0.03%.
This means that with 95% confidence, the worst daily loss will not exceed -0.03% (of the investment).
To predict future behaviors, we can implement the Monte Carlo method (also see this [2] and this [3].
# consider a year
days = 365
# Delta t
dt = 1/365
Defining a Monte Carlo function fo the Stock price.
def stock_monte_carlo(start_price, days, mu, sigma):
'''
Function takes in stock price, number of days to run, mean and standard deviation values'''
# An emptry array
price = np.zeros(days)
# Initial Price
price[0] = start_price
# Shock and drift
shock = np.zeros(days)
drift = np.zeros(days)
# Formula: New price = Old price + Old price*(shock + drift)
for x in range(1,days):
shock[x] = np.random.normal(loc=mu*dt,scale=sigma*np.sqrt(dt))
drift[x] = mu * dt
price[x] = price[x-1] + (price[x-1] * (drift[x]+shock[x]))
return price
def Monte_Carlo_Analysis(Inp, mu, sigma, N=1e2, days = days, Data = Data):
# get the data for each symbol
df = Data[Data.Symbol == Inp].drop(columns=['Symbol'])
# set the last entry of the open column as the starting price
start_price = df['Open'][-1]
# Ouput Figure
N = int(N)
fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(16, 8))
for run in range(100):
_ = plt.plot(stock_monte_carlo(start_price, days, mu, sigma))
_ = ax.set_xlabel('Days')
_ = ax.set_ylabel('Price')
_ = ax.set_title('Monte Carlo Analysis for %s' % Symbols_Dic[Inp], weight='bold', fontsize = 16)
_ = ax.set_xlim([0,days])
return df
def Final_price_distribution_simulations(Inp, mu, sigma, N= 1e4, days = days, Data = Data):
# get the data for each symbol
df = Data[Data.Symbol == Inp].drop(columns=['Symbol'])
# set the last entry of the open column as the starting price
start_price = df['Open'][-1]
# Simulations array
N = int(N)
simulations = np.zeros(N)
# Progress Bar
Counter = 0
Progress_Bar = progressbar.ProgressBar(maxval= N, widgets=[progressbar.Bar('#', '|', '|'), progressbar.Percentage()])
Progress_Bar.start()
for i in range(N):
simulations[i] = stock_monte_carlo(start_price, days, mu, sigma)[days-1]
Counter+=1
Progress_Bar.update(Counter)
Progress_Bar.finish()
return simulations
def Final_price_distribution_plot(simulations, Inp, Data = Data):
# get the data for Inp teach
df = Data[Data.Symbol == Inp].drop(columns=['Symbol'])
# set the last entry of the open column as the starting price
start_price = df['Open'][-1]
# Output Figure
fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(16, 8))
q = np.percentile(simulations, 1)
_ = ax.hist(simulations, bins='auto', color = '#34495e')
_ = plt.figtext(0.75, 0.80, "Start price: $%.2f" % start_price, fontsize = 12)
_ = plt.figtext(0.75, 0.75, "Mean final price: $%.2f" % simulations.mean(), fontsize = 12)
_ = plt.figtext(0.75, 0.70, "VaR(0.99): $%.2f" % (start_price -q,), fontsize = 12)
_ = plt.figtext(0.15,0.665, "q(0.99): $%.2f" % q, fontsize = 12)
_ = ax.set_xlim()
_ = ax.axvline(x=q, linewidth=4, color='#e74c3c')
_ = ax.set_title("Final price distribution for %s after %s days" % (Symbols_Dic[Inp], days), weight='bold', fontsize = 16)
Symbol = 'AAPL'
# mean
mu = All_returns.mean()[Symbol]
# standard deviation
sigma = All_returns.std()[Symbol]
_ = Monte_Carlo_Analysis(Symbol, mu = mu, sigma = sigma)
The frequencies of different outcomes simulated form a Bell curve. The most likely return is in the middle of the curve. This means there is an equal chance that the actual return will be higher or lower than that value.
Simulations = Final_price_distribution_simulations(Symbol, mu = mu, sigma = sigma)
Final_price_distribution_plot(Simulations, Symbol)
|#########################################################################|100%
See more details about Value at Risk (VaR) [4].
Symbol = 'MSFT'
# mean
mu = All_returns.mean()[Symbol]
# standard deviation
sigma = All_returns.std()[Symbol]
_ = Monte_Carlo_Analysis(Symbol, mu = mu, sigma = sigma)
Simulations = Final_price_distribution_simulations(Symbol, mu = mu, sigma = sigma)
Final_price_distribution_plot(Simulations, Symbol)
|#########################################################################|100%
Symbol = 'TSM'
# mean
mu = All_returns.mean()[Symbol]
# standard deviation
sigma = All_returns.std()[Symbol]
_ = Monte_Carlo_Analysis(Symbol, mu = mu, sigma = sigma)
Simulations = Final_price_distribution_simulations(Symbol, mu = mu, sigma = sigma)
Final_price_distribution_plot(Simulations, Symbol)
|#########################################################################|100%